<script setup lang="ts" name="RulerWrapper">
import RulerLine from './rulerLine.vue'
import CanvasRuler from './canvasRuler.vue'

const emits = defineEmits(['onUpdateLines'])

const props = defineProps({
  scale: Number,
  ratio: Number,
  thick: Number,
  vertical: {
    type: Boolean,
    default: true
  },
  width: {
    type: Number,
    default: 200
  },
  height: {
    type: Number,
    default: 200
  },
  start: {
    type: Number,
    default: 0
  },
  lines: {
    type: Array,
    default: () => []
  },
  shadowStart: {
    type: Number
  },
  shadowLength: {
    type: Number
  },
  isShowReferLine: {
    type: Boolean
  },
  isShowRuler: {
    type: Boolean
  }
})

const lineList: any = toRef(props, 'lines')
const showIndicator = ref(false)
const valueNum = ref(0)
const rwClassName = computed(() => {
  const className = props.vertical ? 'v-container' : 'h-container'
  return className
})
const rwStyle = computed(() => {
  const hContainer = {
    width: `calc(100% - ${props.thick}px)`,
    height: `${props.thick! + 1}px`,
    left: `${props.thick}` + 'px'
  }
  const vContainer = {
    width: `${props.thick && props.thick + 1}px`,
    height: `calc(100% - ${props.thick}px)`,
    top: `${props.thick}` + 'px'
  }
  return props.vertical ? vContainer : hContainer
})

const actionStyle = computed(() => {
  const actionStyle = props.vertical
    ? { left: props.thick + 'px' }
    : { top: props.thick + 'px' }
  return actionStyle
})

const indicatorStyle = computed(() => {
  const indicatorOffset = (valueNum.value - props.start) * props.scale!
  let positionKey = 'top'
  positionKey = props.vertical ? 'top' : 'left'
  return {
    [positionKey]: indicatorOffset + 'px'
  }
})

const handleNewLine = (value: number) => {
  lineList.value.push(value)
  emits('onUpdateLines', lineList.value)
}

const handleLineRelease = (value: number, index: number) => {
  // 左右或上下超出时, 删除该条对齐线
  const offset = value - props.start
  const maxOffset =
    (props.vertical ? props.height : props.width) / props.scale!
  if (offset < 0 || offset > maxOffset) {
    handleLineRemove(index)
  } else {
    lineList.value[index] = value
    emits('onUpdateLines', lineList.value)
  }
}

const handleLineRemove = (index: any) => {
  lineList.value.splice(index, 1)
  emits('onUpdateLines', lineList.value)
}
</script>

<template>
  <div :class="rwClassName" :style="rwStyle">
    <CanvasRuler v-if="isShowRuler" :vertical="vertical" :scale="scale" :width="width" :height="height" :start="start" :ratio="ratio" :shadow-start="shadowStart" :shadow-length="shadowLength" v-model:valueNum="valueNum" v-model:showIndicator="showIndicator" @onAddLine="handleNewLine"></CanvasRuler>
    <div v-show="isShowReferLine" class="lines">
      <RulerLine v-for="(v, i) in lineList" :key="v + i" :index="i" :value="v >> 0" :scale="scale" :start="start" :thick="thick" :vertical="vertical" :is-show-refer-line="isShowReferLine" @onRemove="handleLineRemove" @onRelease="handleLineRelease"></RulerLine>
    </div>
    <div v-show="showIndicator" :class="['indicator', props.vertical ? 'bottom' : 'left']" :style="indicatorStyle">
      <div class="value" :style="actionStyle">{{ valueNum }}</div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.line {
  position: absolute;
}

.h-container,
.v-container {
  position: absolute;

  .indicator {
    position: absolute;
    pointer-events: none;

    .value{
      position: absolute;
    }
  }

  .lines {
    pointer-events: none;
  }

  &:hover .lines {
    pointer-events: auto;
  }
}

.h-container {
  top: 0;

  .line {
    top: 0;
    height: 100vh;
    padding-left: 5px;

    .action {
      transform: translateX(-24px);

      .value {
        margin-left: 4px;
      }
    }
  }

  .indicator {
    top: 0;
    height: 100vw;

    &.left {
      border-left: 1px dashed var(--el-color-primary);
    }

    .value {
      width: auto;
      margin-top: 4px;
      margin-left: 4px;
      padding: 0 2px;
    }
  }
}

.v-container {
  left: 0;

  .line {
    left: 0;
    width: 100vw;
    padding-top: 5px;

    .action {
      flex-direction: column;
      transform: translateY(-24px);

      .value {
        margin-top: 4px;
      }
    }
  }

  .indicator {
    left: 0;
    width: 100vw;

    &.bottom {
      border-bottom: 1px dashed var(--el-color-primary);
    }

    .value {
      left: 0;
      width: auto;
      margin-top: 4px;
      margin-left: 4px;
      padding: 0 2px;
    }
  }
}
</style>
